package com.demo.java.OD351_400.OD395;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

/**
 * @author bug菌
 * @Source 公众号：猿圈奇妙屋
 * @des： 【积分奖励(C&D卷)】问题
 * @url： https://blog.csdn.net/weixin_43970743/article/details/146244137
 */
public class OdMain {
    public static void main(String[] args) {
        // 读数据
        try (Scanner sc = new Scanner(System.in)) {
            int n = sc.nextInt(); // 任务数量
            int t = sc.nextInt(); // 最大时间

            // 二维数组构造map
            // 首先初始化二维数组
            List<Integer>[] list = new ArrayList[t + 1];
            for (int i = 0; i < t + 1; i++) {
                list[i] = new ArrayList<>();
            }

            // 读<截止时间, 积分>的数对
            for (int i = 0; i < n; i++) {
                int endTime = sc.nextInt(); // 截止时间
                int value = sc.nextInt();   // 积分
                // 维护 截止时间 -> 积分 的一对多关系
                list[Math.min(endTime, t)].add(value);
            }

            // 计算最大得分并输出
            int ans = calculateMaxScore(list, t);
            System.out.println(ans);
        }
    }

    // 计算最大得分
    private static int calculateMaxScore(List<Integer>[] list, int t) {
        int ans = 0; // 最大得分
        List<Integer> waitList = new ArrayList<>(); // 存储当前时间段内的任务

        // 倒贪心
        for (int i = t; i > 0; i--) {
            // 我们考虑时间戳t时，考虑的是[t-1,t]这个区间的任务执行
            waitList.addAll(list[i]);

            // 取出优先队列中最大的一个任务
            if (!waitList.isEmpty()) {
                // 使用 Collections.max 获取当前时间段内的最大得分
                int max = Collections.max(waitList);
                ans += max;
                waitList.remove(Integer.valueOf(max)); // 移除已选择的任务
            }
        }
        return ans;
    }
}